package com.example.analysis.service.impl;

import com.example.analysis.entity.Quest;
import com.example.analysis.exception.BusinessException;
import com.example.analysis.mapper.EvaluateListStudentDao;
import com.example.analysis.mapper.EvaluateSupervisionDao;
import com.example.analysis.mapper.QuestDao;
import com.example.analysis.service.EvaluationStudentService;
import com.example.analysis.utils.*;
import com.example.analysis.vo.*;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class EvaluationStudentServiceImpl implements EvaluationStudentService {
    @Resource
    private EvaluateListStudentDao evaluateListStudentDao;
    @Resource
    private EvaluateSupervisionDao evaluateSupervisionDao;
    @Resource
    private QuestDao questDao;
    private final double[] deltas = new double[]{0, 0.03, 0.05, 0.1, 0.15};

    @Override
    public List<ReliabilityVO> reliabilityAnalysis(String type, String courseId, String teacherId) {
        // 查询问卷
        List<Quest> questList = questDao.selectQuest(type);
        double[][] data = loadData(type, courseId, teacherId, questList);
        if (data.length == 0)
            return null;
        for (double[] one : data) {
            if (one.length == 0)
                return null;
        }
        // 有数据，进行分析
        List<ReliabilityVO> reliabilityVOList = new ArrayList<>();
        for (double delta : deltas) {
            double[][] newData = filterData(data, delta);
            ReliabilityVO reliabilityVO = ReliabilityAnalysis.analysis(newData, questList);
            reliabilityVOList.add(reliabilityVO);
        }
        return reliabilityVOList;
    }

    @Override
    public ValidityVO validityAnalysis(String type, int factorNum, double delta) throws BusinessException {
        List<Quest> questList = questDao.selectQuest(type);
        double[][] data = loadData(type, questList);
        double[][] filterData = filterData(data, delta);
        return FactorAnalysis.analysis(filterData, questList, factorNum);
    }

    @Override
    public List<ResultVO> itemAnalysis(String type, double quantile, double delta) {
        System.out.println("type = " + type + ", quantile = " + quantile);
        List<Quest> questList = questDao.selectQuest(type);
        double[][] rawData = loadData(type, questList);
        double[][] data = filterData(rawData, delta);
        List<ResultVO> resultVOList = new ArrayList<>();
        for (int i = 0; i < data.length; i++) {
            List<double[]> groups = DifferenceAnalysis.divideGroups(data[i], quantile);
            double[] res = DifferenceAnalysis.twoGroupAnalysis(groups);
            // 项信息
            List<ItemVO> itemVOList = new ArrayList<>();
            ItemVO itemVO1 = new ItemVO(0, 0, 0, groups.get(0), "高分组");
            ItemVO itemVO2 = new ItemVO(0, 0, 0, groups.get(1), "低分组");
            itemVOList.add(itemVO1);
            itemVOList.add(itemVO2);
            resultVOList.add(new ResultVO(res[0], res[1], itemVOList, questList.get(i).getQuestEvaluate()));
        }
        return resultVOList;
    }

    @Override
    public List<WeightVO> entropyWeight(String type, List<String> processType, double delta) {
        List<Quest> questList = questDao.selectQuest(type);
        double[][] data = loadData(type, questList);
        double[][] filterData = filterData(data, delta);
        double[][] res = EntropyWeight.calcWeight(filterData, processType);

        List<WeightVO> weightVOList = new ArrayList<>();
        for (int i = 0; i < res[0].length; i++) {
            weightVOList.add(new WeightVO(questList.get(i).getQuestEvaluate(), res[0][i], res[1][i], res[2][i]));
        }
        return weightVOList;
    }

    @Override
    public List<Quest> getQuest(String type) {
        return questDao.selectQuest(type);
    }

    private double[][] loadData(String type, String courseId, String teacherId, List<Quest> questList) {
        // 获取每个问题的分数
        List<double[]> allItemScores = new ArrayList<>();
        if ("1".equals(type)) {
            for (Quest q : questList) {
                double[] itemScores = evaluateListStudentDao.selectScoreByParam(q.getQuestId(), courseId, teacherId);
                allItemScores.add(itemScores);
            }
        } else {
            for (Quest q : questList) {
                double[] itemScores = evaluateSupervisionDao.selectScoreByParam(q.getQuestId(), courseId, teacherId);
                allItemScores.add(itemScores);
            }
        }
        return allItemScores.toArray(new double[0][]);
    }

    private double[][] loadData(String type, List<Quest> questList) {
        // 获取每个问题的分数
        List<double[]> allItemScores = new ArrayList<>();
        if ("1".equals(type)) {
            for (Quest q : questList) {
                double[] itemScores = evaluateListStudentDao.selectScoreByQuestId(q.getQuestId());
                allItemScores.add(itemScores);
            }
        } else {
            for (Quest q : questList) {
                List<Double> itemScores = evaluateSupervisionDao.selectScoreByQuestId(q.getQuestId());
                Double[] array = itemScores.toArray(itemScores.toArray(new Double[0]));
                allItemScores.add(transform(array));
            }
        }
        return allItemScores.toArray(new double[0][]);
    }

    // 转换类型
    private double[] transform(Double[] data) {
        double[] ret = new double[data.length];
        for (int i = 0; i < data.length; i++) {
            ret[i] = data[i] == null ? 0 : data[i];
        }
        return ret;
    }

    // 去掉最高/低的delta
    private double[][] filterData(double[][] data, double delta) {
        List<double[]> filteredData = new ArrayList<>();
        int from;
        for (double[] one : data) {
            Arrays.sort(one);
            from = (int) (one.length * delta);
            double[] filter = Arrays.copyOfRange(one, from, one.length - from);
            filteredData.add(filter);
        }
        return filteredData.toArray(double[][]::new);
    }
}
